package io.zhengsh.juc;

import java.sql.Time;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

/**
 * 要求：t1 线程等待 3 秒，3 秒后， t2 线程唤醒 t1 线程继续工作
 * <p>
 * 有以下几种异常情况：
 * wait 方法和 notify 方法, 两个都去掉同步代码块后看运行效果
 * 异常情况
 * Exception in thread "B" java.lang.IllegalMonitorStateException
 * Exception in thread "B" java.lang.IllegalMonitorStateException
 * <p>
 * 结论
 * <p>
 * Object 类中的 wait、notify 、notifyAll 用与线程等待和唤醒的方法，都必须要在  synchronized 内部执行（必须要使用 synchronized 关键在）
 */
public class LockSupportDemo {

    static Object objectLock = new Object();

    public static void main(String[] args) throws InterruptedException {

        Thread a = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + " \t ======= 进入锁");
            LockSupport.park();
            System.out.println(Thread.currentThread().getName() + "\t ======== 被唤醒");
        }, "A");
        a.start();

        TimeUnit.SECONDS.sleep(3);

        Thread b = new Thread(() -> {
            LockSupport.unpark(a);
            System.out.println(Thread.currentThread().getName() + "\t ======== 通知了");
        }, "A");
        b.start();
    }

    private static void objectLock1() {
        // 1、wait、notify 需要配合 synchronized 使用
        new Thread(() -> {
            synchronized (objectLock) {
                System.out.println(Thread.currentThread().getName() + "\t =======> 进入锁");
                try {
                    objectLock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "\t =======> 被唤醒");
            }
        }, "A").start();

        new Thread(() -> {
            synchronized (objectLock) {
                objectLock.notify();
                System.out.println(Thread.currentThread().getName() + "\t =======> 发起通知");
            }
        }, "B").start();
    }
}
